package com.example.validdemo.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.example.validdemo.model.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.ConstraintViolationException;
import java.util.Map;


/**
 * @author Bx_Hu
 */
@ControllerAdvice
@ResponseBody
@Slf4j
public class WebExceptionController extends ApiController {


    /**
     * 参数效验异常处理
     */
    @ExceptionHandler(value = BindException.class)
    public R<String> handleBindException(BindException e) {
        log.error("参数校验异常", e);
        if (null != e.getBindingResult()
                .getFieldError()
                && !ObjectUtil.isEmpty(e.getBindingResult()
                .getFieldError()
                .getDefaultMessage())) {
            return failed(e.getBindingResult()
                    .getFieldError()
                    .getDefaultMessage());
        }
        return failed("参数校验失败");
    }

    /**
     *  @Valid 参数效验异常处理
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public R<String> myMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("参数解析失败", e);
        final String[] msg = {""};
        Map<String, String> errorMaps = CollUtil.newHashMap();
        e.getBindingResult()
                .getFieldErrors()
                .forEach(error -> {
                    String field = error.getField();
                    String message = error.getDefaultMessage();
                    errorMaps.put(field, message);
                    if (StrUtil.isBlank(msg[0])) {
                        msg[0] = message;
                    }
                });
        log.error("校验失败参数 = {}",errorMaps);
        return failed(msg[0]);
    }


    /**
     * 单参数 @NotNull @NotBlank @NotEmpty 效验异常处理
     */
    @ExceptionHandler(value = ConstraintViolationException.class)
    public R<String> handleConstraintViolationException(ConstraintViolationException e) {
        log.error("参数校验异常", e);
        final String[] msg = {""};
        Map<String, String> errorMaps = CollUtil.newHashMap();
        e.getConstraintViolations()
                .forEach(error -> {
                    String field = error.getPropertyPath()
                            .toString();
                    String message = error.getMessageTemplate();
                    errorMaps.put(field, message);
                    if (StrUtil.isBlank(msg[0])) {
                        msg[0] = message;
                    }
                });
        log.error("校验失败参数 = {}",errorMaps);
        return failed(msg[0]);
    }


}

